import React from 'react';
import { withScriptjs, withGoogleMap, GoogleMap, Marker } from 'react-google-maps';
import SearchBox from 'react-google-maps/lib/components/places/SearchBox';
import { Spin, Row } from 'antd';
import { GOOGLE_KEY } from '../config';

const EnhanceGoogleMap = withScriptjs(
    withGoogleMap(({ defaultPosition, onChange, onSelect, visible }) => {
        const [position, setPosition] = React.useState(defaultPosition);
        const searchRef = React.useRef(null);
        const mapRef = React.useRef(null);
        const inputRef = React.useRef(null);
        const geocoderRef = React.useRef(null);

        const handlePlaceChange = () => {
            const [currentPlace] = searchRef.current.getPlaces();
            const { geometry = {}, name } = currentPlace;
            const { location = {} } = geometry;
            setPosition(location);
            onSelect(name);
        };

        React.useEffect(() => {
            if (!visible && inputRef.current) {
                inputRef.current.value = '';
            }
        }, [visible]);

        React.useEffect(() => {
            if (!window.google || !position) {
                return;
            }
            const { lat, lng } = position;
            const finalLat = typeof lat === 'function' ? lat() : lat;
            const finalLng = typeof lng === 'function' ? lng() : lng;
            geocoderRef.current = geocoderRef.current || new window.google.maps.Geocoder();
            const latLng = new window.google.maps.LatLng(finalLat, finalLng);

            geocoderRef.current.geocode({ latLng }, (res = []) => {
                if (res) {
                    const [address = {}] = res;
                    const { formatted_address: formattedAddress } = address;
                    onChange({ currentPosition: { lat: finalLat, lng: finalLng }, formattedAddress });
                }
            });
        }, [position]);

        const handleMapClick = _value => {
            const { latLng = {} } = _value;
            setPosition(latLng);
        };

        return (
            <GoogleMap
                ref={mapRef}
                onClick={handleMapClick}
                defaultZoom={8}
                center={position}
                options={{ streetViewControl: false, fullscreenControl: false, mapTypeControl: false }}
            >
                <SearchBox
                    ref={searchRef}
                    controlPosition={window.google && window.google.maps.ControlPosition.TOP_LEFT}
                    onPlacesChanged={handlePlaceChange}
                >
                    <input
                        ref={inputRef}
                        type="text"
                        placeholder="请输入关键词"
                        style={{
                            boxSizing: 'border-box',
                            border: '1px solid transparent',
                            width: '500px',
                            height: '40px',
                            marginTop: '24px',
                            marginLeft: '24px',
                            padding: '0 12px',
                            borderRadius: '3px',
                            boxShadow: '0 2px 6px rgba(0, 0, 0, 0.3)',
                            fontSize: '14px',
                            outline: 'none',
                            textOverflow: 'ellipses'
                        }}
                    />
                </SearchBox>
                <Marker position={position} />
            </GoogleMap>
        );
    })
);

const Map = ({ defaultPosition, onChange, onSelect, visible }) => {
    const MAP_URL = `https://maps.googleapis.com/maps/api/js?key=${GOOGLE_KEY}&libraries=places`;
    const containerElement = <div style={{ height: '400px' }} />;
    const mapElement = <div style={{ height: '100%' }} />;
    const loadingComponent = (
        <Row type="flex" justify="center" align="middle" style={{ height: '100%' }}>
            <Spin />
        </Row>
    );

    return (
        <EnhanceGoogleMap
            visible={visible}
            defaultPosition={defaultPosition}
            onChange={onChange}
            onSelect={onSelect}
            googleMapURL={MAP_URL}
            loadingElement={loadingComponent}
            containerElement={containerElement}
            mapElement={mapElement}
        />
    );
};

export default Map;
